package nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
 * @author 杜伟毅
 * @version 1.0
 * @since 2024/09/28
 * nio服务端
 */
public class NioSelector {
    public static void main(String[] args) throws IOException {
        // 第一点：创建服务器
        ServerSocketChannel server = ServerSocketChannel.open();
        // 绑定端口
        server.bind(new InetSocketAddress(6667));
        // 配置成非阻塞式的Channel
        server.configureBlocking(false);
        // 创建一个IO多路复用服务器
        Selector selector = Selector.open();
        // 注册
        server.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            // 阻塞的方法，返回值代表发生事件的通道的个数
            //0 超时
            //-1 错误
            selector.select();
            // 只要走到这里，必然说明发生了事件，有可读、可写、可连接的channel
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while (iterator.hasNext()) {
                SelectionKey selectionKey = iterator.next();
                // 这个事件一旦处理了之后就删除，不然会重复处理
                iterator.remove();

                if (selectionKey.isAcceptable()) {
                    // 有人过来连我了, 三次握手
                    System.out.println("有人过来连我了");
                    SocketChannel accept = server.accept();
                    accept.configureBlocking(false);
                    // 注册为可读状态
                    accept.register(selector, SelectionKey.OP_READ,ByteBuffer.allocate(1024));  // 修改这一行
                }

                if (selectionKey.isReadable()) {
                    // 有信息可读
                    System.out.println("有信息可读了");
                    SocketChannel channel = (SocketChannel) selectionKey.channel();
                    ByteBuffer buffer = ByteBuffer.allocate(1024);  // 确保分配一个Buffer
                    int bytesRead = channel.read(buffer);
                    if (bytesRead > 0) {
                        buffer.flip(); // 切换到读模式
                        System.out.println(new String(buffer.array(), 0, buffer.limit()));
                    }
                }
            }
        }
    }
}